/*
 * DestroyableGameObject.java
 *
 * Created on 28. April 2007, 15:19
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package de.tor.obj;

import com.golden.gamedev.engine.BaseIO;
import com.golden.gamedev.object.AnimatedSprite;
import com.golden.gamedev.object.Sprite;
import com.golden.gamedev.object.sprite.VolatileSprite;
import com.golden.gamedev.util.ImageUtil;
import de.tor.SpaceTiger;
import de.tor.loaders.Level;
import de.tor.loaders.Player;
import de.tor.obj.action.AbstractMovement;
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author Charon
 */
public abstract class TorridityGameObject extends AnimatedSprite{
    
    private AbstractMovement mMovement;
    private int iMaxHealth = 0;
    private int iHealth = 0;
    private int iCollisionDamage = 0;
    private boolean bIsDestructable = false;
    
    private VolatileSprite mDestructionAnim = null;
    private Level mLevel = null;
    private List<AbstractWeapon> mWeapons = null;
    private boolean bIsShooting = false;
    
    private double dRotation = 0;
    private Sprite mTrackedObject = null;
    
    public TorridityGameObject(Level pLevel, BufferedImage pView){
        super(new BufferedImage[]{pView});
        setAnimate(false);
        mLevel = pLevel;
        mWeapons = new LinkedList();
        initObject();
    }
    
    public TorridityGameObject(Level pLevel, BufferedImage[] pView){
        super(pView);
        setAnimate(true);
        setLoopAnim(true);
        mLevel = pLevel;
        mWeapons = new LinkedList();
        initObject();
    }
    
    public abstract void initObject();
    
    public List<AbstractWeapon> getWeaponList(){
        return mWeapons;
    }
    
    public void addWeapon(AbstractWeapon pWeapon){
        mWeapons.add(pWeapon);
    }
    
    public Level getLevel(){
        return mLevel;
    }
    
    public void setMovement(AbstractMovement pMovement){
        mMovement = pMovement;
    }
    
    public boolean isDestructable(){
        return bIsDestructable;
    };
    
    public void setDestructable(boolean v) {
        bIsDestructable = v;
    }
    
    public int getHealth(){
        return iHealth;
    }
    
    public void setHealth(int v){
        iHealth = v;
    }
    
    public void doDamage(int v){
        if(isDestructable()){
            iHealth -= v;
        }
    }
    
    public int getCollisionDamage(){
        return iCollisionDamage;
    }
    
    public void setCollisionDamage(int v){
        iCollisionDamage = v;
    }
    
    public boolean isDestroyed(){
        if(!isDestructable()){
            return false;
        }else{
            return (getHealth() <= 0);
        }
    }
    
    public Sprite getTrackedObject(){
        return mTrackedObject;
    }
    
    public void setTracking(Sprite pTrackedObject){
        mTrackedObject = pTrackedObject;
    }
    
    public VolatileSprite getDestructionAnimation(){
        if(mDestructionAnim == null) return null;
        mDestructionAnim.setLocation(getX()-getWidth()/2, getY()-getHeight()/2);
        return mDestructionAnim;
    }
    
    public void setDestructionAnimation(VolatileSprite seq){
        mDestructionAnim = seq;
    }
    
    public abstract void updateTorridityGameObject(long elapsedTime);
    
    public void setShoothing(boolean v){
        bIsShooting = v;
    }
    
    public boolean isShooting(){
        return bIsShooting;
    }
    
    public void setRotation(double v){
        dRotation = v;
        for(AbstractWeapon weapon : mWeapons){
            weapon.setRotation(dRotation);
        }
    }
    
    public double getRotation(){
        return dRotation;
    }
    
    public void updateTracking(){
        double xPlayer = mTrackedObject.getScreenX();
        xPlayer +=mTrackedObject.getWidth()/2;
        double yPlayer = mTrackedObject.getScreenY();
        yPlayer += mTrackedObject.getHeight()/2;
        
        double thisX = getScreenX();
        double thisY = getScreenY();
        thisX += getWidth()/2;
        thisY += getHeight()/2;
        
        double dist = Math.sqrt(Math.pow(xPlayer - thisX, 2) + Math.pow(yPlayer - thisY, 2));
        double h = Math.abs(xPlayer - thisX);
        double rad = Math.asin(h/dist);
        double deg = Math.abs((rad * (360 / (2*Math.PI))));
        
        if((xPlayer >= thisX+5) && (yPlayer < thisY+5)){
            // 1. quadrant
        }else if((xPlayer >= thisX-5) && (yPlayer >= thisY-5)){
            // 2. quadrant
            deg = 180 - deg;
        }else if((xPlayer <= thisX+5) && (yPlayer > thisY-5)){
            // 3. quadrant
            deg += 180;
        }else{
            // 4. quadrant
            deg = 360 - deg;
        }
        
        setRotation(deg);
    }
    
    public void update(long elapsedTime){
        super.update(elapsedTime);
        if(getTrackedObject() != null){
            updateTracking();
        }
        if(isShooting()){
            for(AbstractWeapon weapon : mWeapons){
                AbstractProjectile projectile = weapon.fireShot(elapsedTime);
                if(projectile != null){
                    projectile.setLayer(getLayer()-1);
                    getLevel().firePlayerProjectileEvent(projectile);
                }
            }
        }
        if(mMovement != null){
            mMovement.update(elapsedTime);
            setX(mMovement.getXPos());
            setY(mMovement.getYPos());
            setHorizontalSpeed(mMovement.getHorizontalSpeed());
            setVerticalSpeed(mMovement.getVerticalSpeed());
        }
        updateTorridityGameObject(elapsedTime);
    }
    
    public void render(Graphics2D g){
        AffineTransform before = g.getTransform();
        double rad = dRotation / (360 / (2*Math.PI));
        g.setTransform(AffineTransform.getRotateInstance(rad, getScreenX() + getWidth()/2, getScreenY() + getHeight()/2));
        super.render(g);
        g.setTransform(before);
       /* Composite old = g.getComposite();
       // g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)Math.random()));
        
        g.drawImage(test,(int)getScreenX(),(int)getScreenY(),null);
        
        // return to old composite
        g.setComposite(old);*/
        
    }
}
